#include "app_ip.h"
#include "sensor_service.h"
#include "tftp_server.h"
#include "app_ble_irq_handle.h"
#include "stm32l0xx_nucleo.h"
#include "error.h"
/*private variable*/
extern volatile uint8_t hfc_state;
extern uint16_t ipRxTxServHandle, ipRxTxWriteCharHandle, ipRxTxNotifyCharHandle;
static uint16_t txPacketGroup = 0, txBufReminedNumber = 0, groupCount = 0;
volatile static uint8_t ip_tx_flag = 0;

__align(4) uint8_t bleDataBufRx[RX_BUF_LEN];
__align(4) uint8_t bleDataBufTx[TX_BUF_LEN];

/*private function*/
static void app_ip_tx_transmite_data(uint8_t* data, uint16_t len);

void app_ip_rx_receive_data(uint8_t* data, uint8_t len)
{
    uint16_t _sequenceNumber = 0;
    ble_data_packet_t* dataPkt = (void*)data;
    static uint16_t sn_flag = 0;
 
    _sequenceNumber = dataPkt->ack & SN_MASK;
    
    if(_sequenceNumber == 0x00){
        sn_flag = 0;
    }
    
    if(sn_flag == _sequenceNumber){
     
        if(((_sequenceNumber * 19) + len - 1) > RX_BUF_LEN)
            app_fault_handle(APP_IP_RX_BUF_OVER_ERROR);
        
        memcpy(&bleDataBufRx[_sequenceNumber * 19], dataPkt->payload, len - 1);
        if(((_sequenceNumber) * 19 + (len - 1)) >= (htons(udp_hdr_rx->len) + 8))
        {
            tftp_server_input();
        }
        sn_flag = _sequenceNumber + 1;
    }
}

void app_tftp_to_ip(uint16_t len)
{
    uint16_t PktLen = 0;
		
    memcpy(udp_hdr_tx, udp_hdr_rx, 6);
    udp_hdr_tx->len = htons(len);
    PktLen = len + 8;
    
    groupCount = 0;
    txPacketGroup = PktLen / SINGLE_PACKET_LEN;
    txBufReminedNumber = PktLen % SINGLE_PACKET_LEN ;
    
    ip_tx_flag = app_ip_tx_enable;
}

void app_ip_tx(void)
{
    if(ip_tx_flag == app_ip_tx_enable){
			
        if(groupCount < txPacketGroup ){
            app_ip_tx_transmite_data(&udp_payload_tx[groupCount * SINGLE_PACKET_LEN], SINGLE_PACKET_LEN);
        }
        
        if( groupCount == txPacketGroup){
					
            app_ip_tx_transmite_data(&udp_payload_tx[groupCount * SINGLE_PACKET_LEN], txBufReminedNumber);
        }
        
        ip_tx_flag = app_ip_tx_disable;
        
    }
}

void app_ip_update_value_callback(uint8_t status)
{
#if PRINTF_DEBUG
    printf("status:%x\n",status);
#endif
   if(status != BLE_STATUS_INSUFFICIENT_RESOURCES){
        groupCount++;  
   }
   
   if(status != BLE_STATUS_SUCCESS)
   {
#if PRINTF_DEBUG
        printf("char update error\n");
#endif
   }
   
   if(groupCount <= txPacketGroup)
       ip_tx_flag = app_ip_tx_enable;

}

static void app_ip_tx_assemble_sequence_number(uint8_t* data)
{
    *data = groupCount;

}

static void app_ip_tx_transmite_data(uint8_t* data, uint16_t len)
{
    uint8_t txSingleBuf[SINGLE_PACKET_LEN + 1] = {0}; 
    
    if(len > 0){
        app_ip_tx_assemble_sequence_number(txSingleBuf);       
        memcpy(txSingleBuf + 1, data, len);
#if PRINTF_DEBUG
        printf("tx:\n");
        for(uint8_t i = 0; i < len + 1; i++)
        {
            printf("%x,",txSingleBuf[i]);
        }
        printf("\n");
#endif
        hfc_state = FALSE;
        aci_gatt_update_char_value(ipRxTxServHandle,ipRxTxNotifyCharHandle, 0, 20, txSingleBuf);
    }
}

